package controller;

import controller.commands.ExecuteCommand;
import core.BoxNode;
import core.Node;
import core.TriggerPort;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import model.codebehind.CodeModel;
import model.graphic.GraphicModel;
import model.graphic.objects.GBoxNode;
import model.graphic.objects.Graphical;
import view.GUI.LabelReader;

/**
 *
 * @author Jelle, modified by Ben
 */
public class Serializer {

    private GraphicModel gmodel;
    private CodeModel cmodel;
    private String fileName;
    private GBoxNode gbn;

    public Serializer(GraphicModel gmodel, CodeModel cmodel, String fileName) {
        this.gmodel = gmodel;
        this.cmodel = cmodel;
        this.fileName = fileName;
    }

    public Serializer(GraphicModel gmodel, CodeModel cmodel, GBoxNode gbn, String fileName) {
        this(gmodel,cmodel,fileName);
        this.gbn = gbn;
    }

    public void serialize() {
        ArrayList<Node> list1 = new ArrayList<Node>();
        ArrayList<Graphical> list2 = new ArrayList<Graphical>();
        ExecuteCommand exc = new ExecuteCommand(gmodel.getMainTrigger());
        TriggerPort mainTrigger = exc.getTriggerPort();

        list1 = cmodel.getObjects();
        list2 = gmodel.getObjects();

        FileOutputStream fos = null;
        ObjectOutputStream out = null;
        try {
            fos = new FileOutputStream(fileName);
            out = new ObjectOutputStream(fos);
            out.writeObject(mainTrigger);
            out.writeObject(list1);
            out.writeObject(list2);
            out.writeObject(BidirectionalHashMap.getInstance());
            out.close();

        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public void deserialize() {
        ArrayList<Node> list1 = new ArrayList<Node>();
        ArrayList<Graphical> list2 = new ArrayList<Graphical>();

        FileInputStream fis = null;
        ObjectInputStream in = null;
        try {
            fis = new FileInputStream(fileName);
            in = new ObjectInputStream(fis);
            in.readObject();//TriggerPort: will be ignored
            list1 = (ArrayList<Node>) in.readObject();
            list2 = (ArrayList<Graphical>) in.readObject();
            BidirectionalHashMap.setInstance((BidirectionalHashMap)in.readObject());
            in.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
        cmodel.setObjects(list1);
        gmodel.setObjects(list2);
    }

    public void serializeBoxNode() {
        BoxNode bn = (BoxNode) BidirectionalHashMap.getInstance().get(gbn);
        //deelverzameling sync construeren
        HashMap<Node, Graphical> syncSmall = new HashMap<Node, Graphical>();
        ArrayList<Graphical> all = gbn.getGraphicModel().getAllObjects();
        all.addAll(gbn.getTransmitterObjects());
        for(Graphical g : all){
            syncSmall.put(BidirectionalHashMap.getInstance().get(g), g);
        }

        FileOutputStream fos = null;
        ObjectOutputStream out = null;
        try {
            fos = new FileOutputStream(fileName);
            out = new ObjectOutputStream(fos);
            out.writeObject(gbn);
            out.writeObject(bn);
            out.writeObject(LabelReader.getInstance().getString("info" + gbn.getName()));
            out.writeObject(syncSmall);
            out.close();

        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public GBoxNode deserializeBoxNode() {
        BoxNode inleesBN=null;
        GBoxNode inleesGBN=null;
        FileInputStream fis = null;
        ObjectInputStream in = null;
        try {
            fis = new FileInputStream(fileName);
            in = new ObjectInputStream(fis);
            inleesGBN = (GBoxNode) in.readObject();
            inleesBN = (BoxNode) in.readObject();
            String info = (String)in.readObject();
            LabelReader.getInstance().addString("info" + inleesGBN.getName(), info);
            BidirectionalHashMap.getInstance().put(inleesGBN, inleesBN);
            HashMap<Node, Graphical> syncSmall = (HashMap<Node, Graphical>)in.readObject();
            for(Node n : syncSmall.keySet()){
                BidirectionalHashMap.getInstance().put(syncSmall.get(n), n);
                System.out.println(((Graphical)syncSmall.get(n)).getName());
            }
            in.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
        return inleesGBN;
    }
}
